home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 2
/
The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO
/
clang
/
nn.zip
/
COLLECT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-31
|
7KB
|
320 lines
#include "config.h"
#include "db.h"
#include "news.h"
#define COUNT_RE_REFERENCES /* no of >>> depends on Reference: line */
export int ignore_bad_articles = 1; /* no Newsgroups: line */
export int remove_bad_articles = 0;
import int trace;
static FILE *ix, *data;
/*
* Collect unread articles in current group
*
* On entry, init_group has been called to setup the proper environment
*/
long collect_group(gh)
register group_header *gh;
{
long article_count, temp;
article_number start_collect;
if (gh->last_l_article == 0) {
gh->first_l_article = gh->first_article;
gh->last_l_article = gh->first_l_article - 1;
}
if (gh->last_l_article >= gh->last_article) return 0;
if (gh->index_write_offset) {
ix = open_data_file(gh, 'x', OPEN_UPDATE|MUST_EXIST);
fseek(ix, gh->index_write_offset, 0);
} else
ix = open_data_file(gh, 'x', OPEN_CREATE|MUST_EXIST);
if (gh->data_write_offset) {
data = open_data_file(gh, 'd', OPEN_UPDATE|MUST_EXIST);
fseek(data, gh->data_write_offset, 0);
} else
data = open_data_file(gh, 'd', OPEN_CREATE|MUST_EXIST);
article_count = 0;
start_collect = gh->last_l_article+1;
while (gh->last_l_article < gh->last_article) {
if (s_hangup) break;
gh->last_l_article++;
gh->data_write_offset = ftell(data);
#ifdef NNTP
gh->index_write_offset = ftell(ix);
#endif
if (!db_write_offset(ix, &(gh->data_write_offset)))
write_error();
temp = collect_article(gh, gh->last_l_article);
#ifdef NNTP
if (temp < 0) {
/* connection failed, current article is not collected */
gh->last_l_article--;
article_count = -1;
goto out;
}
#endif
article_count += temp;
}
if (trace && start_collect <= gh->last_l_article) {
log_entry('T', "Col %s (%d to %d) %d",
gh->group_name,
start_collect, gh->last_l_article,
article_count);
fl;
}
gh->data_write_offset = ftell(data);
gh->index_write_offset = ftell(ix);
out:
fclose(data);
fclose(ix);
return article_count;
}
static data_header hdr;
static collect_article(gh, art_num)
register group_header *gh;
article_number art_num;
{
FILE *art_file;
news_header_buffer nhbuf, dgbuf;
article_header art_hdr;
int mode, count;
cross_post_number cross_post_table[256], *cp_ptr;
count = 0;
hdr.dh_number = art_num;
/* get article header */
art_hdr.a_number = art_num;
art_hdr.hpos = (off_t)0;
art_hdr.lpos = (off_t)0;
art_hdr.flag = 0;
mode = FILL_NEWS_HEADER | FILL_OFFSETS | SKIP_HEADER;
if ((gh->group_flag & (G_CONTROL | G_NEVER_DIGEST | G_ALWAYS_DIGEST)) == 0)
mode |= DIGEST_CHECK;
if ((art_file = open_news_article(&art_hdr, mode, nhbuf, (char *)NULL)) == NULL) {
#ifdef NNTP
import nntp_failed;
if (nntp_failed) {
/*
* connection to nntp_server is broken
* stop collection of articles immediately
*/
return -1;
}
#endif
/*
* it is not really necessary to save anything in the data file
* we simply use the index file to get the *first* available article
*/
return 0;
}
if (ignore_bad_articles && news.ng_groups == NULL) {
char *rem = "";
#ifndef NNTP
if (remove_bad_articles) {
unlink(group_path_name);
rem = "removed ";
}
#endif NNTP
log_entry('B', "%sbad article: %s/%ld", rem,
current_group->group_name, (long)art_num);
return 0;
}
/* map cross-postings into a list of group numbers */
hdr.dh_cross_postings = 0;
if (gh->group_flag & G_CONTROL) {
/* we cannot trust the Newsgroups: line in the control group */
/* so we simply ignore it (i.e. use "Newsgroups: control") */
goto dont_digest;
}
if (news.ng_groups) {
char *curg, *nextg;
group_header *gh1;
for (nextg = news.ng_groups, cp_ptr = cross_post_table; *nextg; ) {
curg = nextg;
if (nextg = strchr(curg, ','))
*nextg++ = NUL;
else
nextg = "";
if (strcmp(gh->group_name, curg) == 0) /* break; */
gh1 = gh;
else
if ((gh1 = lookup(curg)) == NULL) continue;
*cp_ptr++ = gh1->group_num;
hdr.dh_cross_postings++;
}
}
if (gh->group_flag & G_NEVER_DIGEST)
goto dont_digest;
/* split digest */
if ((gh->group_flag & G_ALWAYS_DIGEST) || (news.ng_flag & N_DIGEST)) {
int any = 0, cont = 1;
skip_digest_body(art_file);
while (cont && (cont = get_digest_article(art_file, dgbuf)) >= 0) {
if (any == 0) {
/* write DIGEST_HEADER */
build_hdr(2, -art_num, cross_post_table);
count++;
hdr.dh_cross_postings = 0; /* no cross post in sub */
any++;
}
/* write SUB_DIGEST */
build_hdr(1, (article_number)0, (group_number *)NULL);
count++;
}
if (any) goto finish;
}
/* not a digest */
dont_digest:
build_hdr(0, art_num, cross_post_table); /* normal article */
count++;
finish:
fclose(art_file);
return count;
}
static build_hdr(use_digest, art_num, cross_post_table)
int use_digest;
article_number art_num;
cross_post_number *cross_post_table;
{
register char *name, *subj;
char name_buf[NAME_LENGTH+1], subj_buf[256];
int re;
if (use_digest & 1) {
name = digest.dg_from;
subj = digest.dg_subj;
hdr.dh_lines = digest.dg_lines;
hdr.dh_hpos = digest.dg_hpos;
hdr.dh_fpos = (int16)(digest.dg_fpos - hdr.dh_hpos);
hdr.dh_lpos = digest.dg_lpos;
pack_date(&(hdr.dh_date),
digest.dg_date ? digest.dg_date : news.ng_date);
} else {
if (!news.ng_from) news.ng_from = news.ng_reply;
name = news.ng_from;
subj = news.ng_subj;
hdr.dh_lines = news.ng_lines;
hdr.dh_hpos = 0;
hdr.dh_fpos = (int16)(news.ng_fpos);
hdr.dh_lpos = news.ng_lpos;
pack_date(&(hdr.dh_date), news.ng_date);
}
hdr.dh_number = art_num;
/* pack name and write on .nn2 */
if (name) {
hdr.dh_sender_length = pack_name(name_buf, name, NAME_LENGTH);
} else
hdr.dh_sender_length = 0;
/* write subject line on .nn2 */
hdr.dh_subject_length = pack_subject(subj_buf, subj, &re, 255);
#ifdef COUNT_RE_REFERENCES
if (re) re = 0x80;
if (news.ng_ref) {
for (name = news.ng_ref; *name; name++) {
if ((re & 0x7f) == 0x7f) break;
if (*name == '<') re++;
}
}
#endif
hdr.dh_replies = re;
if (use_digest & 2) hdr.dh_subject_length++; /* @ */
/* WRITE hdr, cross postings, name, subject */
db_write_art(data, &hdr);
if (cross_post_table && hdr.dh_cross_postings) {
#ifdef NETWORK_DATABASE
#ifndef NETWORK_BYTE_ORDER
int i;
for (i = 0; i < hdr.dh_cross_postings; i++)
cross_post_table[i] = htonl(cross_post_table[i]);
#endif
#endif
Fwrite((char *)cross_post_table, sizeof(cross_post_number),
(int)hdr.dh_cross_postings, data);
}
if (hdr.dh_sender_length)
Fwrite(name_buf, sizeof(char), (int)hdr.dh_sender_length, data);
if (use_digest & 2) {
putc('@', data);
hdr.dh_subject_length--;
}
if (hdr.dh_subject_length)
Fwrite(subj_buf, sizeof(char), (int)hdr.dh_subject_length, data);
return;
}